<?php

namespace Biz\pockets\modelTrait;

use Doraemon\tools\Log;

trait BizModelTrait
{

    /**
     * 插入单条数据
     * @param array $dataArray
     * @return false | int
     */
    public static function dataInsert(array $dataArray)
    {
        $pdoStatement = static::insert($dataArray);
        if ($pdoStatement->errorCode() !== '00000') {
            return false;
        }
        return static::id();
    }

    /**
     * 批量插入数据
     * @param array $dataArray
     * @return false | int
     */
    public static function dataMultiInsert(array $dataArray)
    {
        $insertCount = 0;

        if (empty($dataArray)) {
            return $insertCount;
        }
        $pdoStatement = static::insert($dataArray);
        if ($pdoStatement->errorCode() !== '00000') {
            return false;
        }
        $insertCount = $pdoStatement->rowCount();
        return $insertCount;
    }

    /**
     * 删除数据（软删除）
     * @param array $where
     * @return bool
     */
    public static function dataSoftDelete(array $where): bool
    {
        if (empty($where) || !isset(static::$deleteField)) {
            return false;
        }
        $data[static::$deleteField] = static::STATUS_DELETE;
        return static::dataUpdate($data, $where);
    }

    /**
     * 删除数据恢复
     * @param array $where
     * @return bool
     */
    public static function dataRecovery(array $where): bool
    {
        if (empty($where) || !isset(static::$deleteField)) {
            return false;
        }
        $data[static::$deleteField] = static::STATUS_NORMAL;
        return static::dataUpdate($data, $where);
    }

    /**
     * 删除数据
     * @param array $where
     * @return bool
     */
    public static function dataForceDelete(array $where): bool
    {
        if (empty($where)) {
            return false;
        }
        $pdoStatement = static::delete($where);
        if ($pdoStatement->errorCode() !== '00000') {
            return false;
        }
        return true;
    }

    /**
     * 数据更新
     * @param array $dataArray
     * @param array $where
     * @param bool $returnRowCount
     * @return bool | int
     */
    public static function dataUpdate(array $dataArray, array $where, bool $returnRowCount = false)
    {
        if (empty($where) || empty($dataArray)) {
            return false;
        }
        $pdoStatement = static::update($dataArray, $where);
        if ($pdoStatement->errorCode() !== '00000') {
            return false;
        }
        if (!$returnRowCount) {
            return true;
        }
        return $pdoStatement->rowCount();
    }

    /**
     * 数据更新
     * @param array $dataArray
     * @param bool $returnRowCount
     * @return bool | int
     */
    public static function dataMultiUpdate(array $dataArray)
    {
        if (empty($dataArray)) {
            return false;
        }
        $rowCount = 0;
        foreach ($dataArray as $item) {
            [$data, $where] = $item;
            $pdoStatement = static::update($data, $where);
            if ($pdoStatement->errorCode() !== '00000') {
                return $rowCount;
            }
            $rowCount += $pdoStatement->rowCount();
        }

        return $rowCount;
    }


    /**
     * 获取单行数据
     * @param array $where
     * @param array $fields
     * @return mixed
     */
    public static function dataSelectInfo(array $where, array $fields = [])
    {
        $fields = empty($fields) ? '*' : $fields;
        $result = static::get($fields, $where);
        //Log::debug('dataSelectInfo', static::log());
        return $result;
    }

    /**
     * 查询数据列表，返回二位数组
     * @param array $where
     * @param mixed $fields
     * @return array | bool
     */
    public static function dataSelect(array $where, $fields = [])
    {
        $fields = empty($fields) ? '*' : $fields;
        $result = static::select($fields, $where);
        //Log::debug('dataSelect', static::log());
        return $result;
    }

    /**
     * 分页查询
     * @param array $where
     * @param array $fields
     * @param int $page
     * @param int $offset
     * @return array|bool
     */
    public static function dataPaginate(array $where, array $fields = [], int $page = 1, int $offset = 20)
    {
        if (!isset($where['ORDER'])) {
            $where['ORDER'] = [
                'id' => 'ASC',
            ];
        }
        $where['LIMIT'] = [
            ($page - 1) * $offset,
            $offset
        ];
        $dataSelected = static::dataSelect($where, $fields);
        return $dataSelected;
    }

    /**
     * 获取给定列的数组
     * @param array $where
     * @param string $field
     * @param $index (键值唯一)
     * @return array | bool
     */
    public static function dataPluck(array $where, string $field, string $index = '')
    {
        if (empty($field)) {
            return false;
        }
        $selectField = empty($index) ? $field : [$field, $index];
        $dataArray = static::select($selectField, $where);
        if (empty($index) || !is_array($dataArray)) {
            return $dataArray;
        }
        return static::dataMap($dataArray, $index, $field);
    }

    /**
     * 获取单个值
     * @param array $where
     * @param string $field
     * @return mixed|null
     */
    public static function dataValue(array $where, string $field)
    {
        $value = static::get($field, $where);
        //Log::debug('dataValue', static::log());
        return $value;
    }

    /**
     * 判断数据是否存在
     * @param array $where
     * @return bool
     */
    public static function dataHas(array $where): bool
    {
        $nRet = static::has($where);
        //Log::debug('dataHas', static::log());
        return $nRet;

    }

    /**
     * 获取查询的数量
     * @param array $where
     * @param string $field
     * @return int
     */
    public static function dataCount(array $where, string $field = ''): int
    {
        $params = [];
        if (!empty($field)) {
            $params[] = $field;
        }
        $params[] = $where;
        $count = static::count(...$params);
        //Log::debug('dataCount', static::log());
        return $count;
    }

    /**
     * 拆分查询 （注意查询的表需要包含自增主键id且只按id排序）
     * @param array $where
     * @param int $size
     * @param callable $callback
     * @return bool
     */
    public static function dataChunk(array $where, int $size, callable $callback): bool
    {
        if (!isset($where['ORDER'])) {
            $where['ORDER'] = ['id' => 'ASC'];
        }
        $where['LIMIT'] = $size;
        $results = static::dataSelect($where);
        if (is_bool($results) && !$results) {
            return false;
        }
        $op = $where['ORDER']['id'] === 'ASC' ? '>' : '<';
        while (count($results) > 0) {
            if ($callback($results) === false) {
                return false;
            }
            $lastRecord = array_pop($results);
            $where["id[$op]"] = $lastRecord['id'];
            $results = static::dataSelect($where);
            if (is_bool($results) && !$results) {
                return false;
            }
        }
        return true;
    }

    /**
     * 获取数据Map
     * @param array $dataArray
     * @param string|null $key
     * @param string|null $columnKey
     * @return array
     */
    public static function dataMap(array $dataArray, $key = 'id', $columnKey = null): array
    {
        if (empty($dataArray)) {
            return [];
        }
        $firstKey = array_key_first($dataArray);
        $firstData = $dataArray[$firstKey];
        $keys = array_keys($firstData);
        if ($key && !in_array($key, $keys)) {
            return [];
        }
        return array_column($dataArray, $columnKey, $key);
    }

}